package com.zjmzxfzhl.integrityconstraint.config;

import cn.hutool.extra.spring.SpringUtil;
import com.zjmzxfzhl.integrityconstraint.annotation.IntegrityConstraintAnnotationAspect;
import com.zjmzxfzhl.integrityconstraint.annotation.SpareImplAnnotationAspect;
import com.zjmzxfzhl.integrityconstraint.service.IntegrityConstraintService;
import com.zjmzxfzhl.integrityconstraint.service.impl.JdbcIntegrityConstraintService;
import com.zjmzxfzhl.integrityconstraint.service.impl.RedisIntegrityConstraintService;
import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry;
import io.github.resilience4j.spelresolver.SpelResolver;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * 业务完整性验证自动装配类
 *
 * @author 庄金明
 */
@Configuration
@ConditionalOnProperty(value = "integrityConstraint.enabled", matchIfMissing = false)
public class IntegrityConstraintAutoConfiguration {

    @Bean
    public SpringUtil springUtil() {
        return new SpringUtil();
    }

    @Bean
    @ConditionalOnMissingBean
    public IntegrityConstraintProperties integrityConstraintProperties() {
        return new IntegrityConstraintProperties();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisIntegrityConstraintService integrityConstraintService(RedisTemplate redisTemplate) {
        return new RedisIntegrityConstraintService(redisTemplate, integrityConstraintProperties());
    }

    @Bean
    public JdbcIntegrityConstraintService jdbcIntegrityConstraintService(JdbcTemplate jdbcTemplate) {
        return new JdbcIntegrityConstraintService(jdbcTemplate, integrityConstraintProperties());
    }

    @Bean
    public SpareImplAnnotationAspect spareImplAnnotationAspect(CircuitBreakerRegistry circuitBreakerRegistry, SpelResolver spelResolver) {
        return new SpareImplAnnotationAspect(circuitBreakerRegistry, spelResolver);
    }

    @Bean
    public IntegrityConstraintAnnotationAspect integrityConstraintAnnotationAspect(IntegrityConstraintService integrityConstraintService, IntegrityConstraintProperties integrityConstraintProperties, BeanFactory beanFactory, SpelExpressionParser spelExpressionParser) {
        return new IntegrityConstraintAnnotationAspect(integrityConstraintService, integrityConstraintProperties, beanFactory, spelExpressionParser);
    }
}
